namespace SimpleWebServices.Web.Mvc
{
    using System;
    using System.Reflection;
    using System.Web.Routing;
    using SimpleWebServices;
    using Xunit;

    public sealed class RoutingAttributeFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<RoutingAttribute>()
                .DerivesFrom<Attribute>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .IsDecoratedWith<AttributeUsageAttribute>()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new RoutingAttribute());
        }

        [Fact]
        public void ctor_string_string()
        {
            Assert.NotNull(new RoutingAttribute("GET, HEAD", "path"));
        }

        [Fact]
        public void ctor_stringEmpty_string()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new RoutingAttribute(string.Empty, "path"));
        }

        [Fact]
        public void ctor_stringNull_string()
        {
            Assert.Throws<ArgumentNullException>(() => new RoutingAttribute(null as string, "path"));
        }

        [Fact]
        public void ctor_string_stringInvalid()
        {
            Assert.Throws<FormatException>(() => new RoutingAttribute("GET, HEAD", "/path"));
        }

        [Fact]
        public void ctor_string_stringEmpty()
        {
            Assert.NotNull(new RoutingAttribute("GET, HEAD", string.Empty));
        }

        [Fact]
        public void ctor_string_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new RoutingAttribute("GET, HEAD", null as string));
        }

        [Fact]
        public void prop_Methods()
        {
            Assert.True(new PropertyExpectations(typeof(RoutingAttribute).GetProperty("Methods"))
                .TypeIs<string>()
                .ArgumentNullException()
                .ArgumentOutOfRangeException(string.Empty)
                .Set("GET, HEAD")
                .Set("POST")
                .Result);
        }

        [Fact]
        public void prop_Path()
        {
            Assert.True(new PropertyExpectations(typeof(RoutingAttribute).GetProperty("Path"))
                .TypeIs<string>()
                .ArgumentNullException()
                .FormatException("/path")
                .Set(string.Empty)
                .Set("path")
                .Result);
        }

        [Fact]
        public void op_Register_RouteCollection_Type_MethodInfo()
        {
            RouteCollection obj = new RouteCollection();

            new RoutingAttribute("GET", "path").Register(obj, typeof(NotFoundController), typeof(NotFoundController).GetMethod("HtmlRepresentation"));

            Assert.Equal<int>(1, obj.Count);
        }

        [Fact]
        public void op_Register_RouteCollectionNull_Type_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new RoutingAttribute("GET", "path").Register(null as RouteCollection, typeof(NotFoundController), typeof(NotFoundController).GetMethod("HtmlRepresentation")));
        }

        [Fact]
        public void op_Register_RouteCollection_TypeNull_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new RoutingAttribute("GET", "path").Register(new RouteCollection(), null as Type, typeof(NotFoundController).GetMethod("HtmlRepresentation")));
        }

        [Fact]
        public void op_Register_RouteCollection_TypeInvalid_MethodInfo()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new RoutingAttribute("GET", "path").Register(new RouteCollection(), typeof(string), typeof(NotFoundController).GetMethod("HtmlRepresentation")));
        }

        [Fact]
        public void op_Register_RouteCollection_Type_MethodInfoNull()
        {
            Assert.Throws<ArgumentNullException>(() => new RoutingAttribute("GET", "path").Register(new RouteCollection(), typeof(NotFoundController), null as MethodInfo));
        }
    }
}